#ifndef _CONFIG_H_
#define _CONFIG_H_
#include <unordered_map>
#include <vector>
#include <variant>
#include <optional>
#include <string>

namespace SEngine
{
    class ConfigNode
    {
    public:
        struct Null {};
        using Object = std::unordered_map<std::string, ConfigNode>;
        using Array = std::vector<ConfigNode>;
    public:
        using Data = std::variant<Null, bool, int, double, std::string, Array, Object>;
        ConfigNode() {}
        template<typename T>
        ConfigNode(T t) : m_data(t) {}
        virtual ~ConfigNode() = default;
        template<typename T>
        std::optional<std::reference_wrapper<T>> GetValue() {
            if (auto ptr = std::get_if<T>(&m_data)) {
                return *ptr;
            }
            return std::nullopt;
        }
    private:
        Data m_data{Null()};
    };

    class IConfigLoader
    {
    public:
        virtual ~IConfigLoader() = default;
        virtual ConfigNode Load(const std::string & path) = 0;
    };

} // namespace SEngine


#endif